#include "ring_queue.hpp"
#include "Task.hpp"
using namespace my_task;
using namespace my_ring_queue;

pthread_mutex_t mtx; // 生产者锁

void *consumer(void *args)
{
    RingQueue<Task> *rq = (RingQueue<Task> *)args;
    std::string ops = "+-*/%";
    while (true)
    {
        int x = rand() % 20 + 1; //[1, 20]
        int y = rand() % 10 + 1; //[1, 10]
        char op = ops[rand() % 5];
        Task t(x, y, op);
        rq->Push(t);
        // 上锁
        pthread_mutex_lock(&mtx);
        cout << "生产者" << pthread_self() << "派发了一个任务：" << x << op << y << "=?" << endl;
        // 解锁
        pthread_mutex_unlock(&mtx);
    }
}
void *productor(void *args)
{
    RingQueue<Task> *rq = (RingQueue<Task> *)args;
    while (true)
    {
        // sleep(1);
        Task t;
        rq->Pop(&t); // 拿到数据
        t();         // 处理数据
        // 上锁
        pthread_mutex_lock(&mtx);
        t.Show(); //显示器也是临界资源
        // 解锁
        pthread_mutex_unlock(&mtx);
    }
}

int main()
{
    RingQueue<Task> *rq = new RingQueue<Task>(); // 定义消费场所(超市)
    srand((long long)time(nullptr));             // 种随机的种子

    pthread_t c0, c1, p0, p1;

    pthread_create(&c0, nullptr, consumer, (void *)rq);
    pthread_create(&c1, nullptr, consumer, (void *)rq);
    pthread_create(&p0, nullptr, productor, (void *)rq);
    pthread_create(&p1, nullptr, productor, (void *)rq);

    pthread_join(c0, nullptr);
    pthread_join(c1, nullptr);
    pthread_join(p0, nullptr);
    pthread_join(p1, nullptr);

    return 0;
}
